<template>
  <div v-loading="loading_async" class="xingkong-docking-config" element-loading-text="加载中...">
    <div class="mag_bg">
      <div class="set_top">
        <el-form
          v-if="getYunxkCfigObj"
          ref="inviteCodeForm"
          :model="getYunxkCfigObj"
          label-width="auto"
          class="box-content"
          label-position="left"
          @click="$event.preventDefault()"
          @submit.prevent="() => {}"
        >
          <el-form-item class="form_item" prop="enabled">
            <template #label>
              <div class="form_item_label">
                <span class="name">开启星空接口</span>
                <span class="tips">
                  <span>是否启用星空接口同步数据，开启后：支持同步；关闭后：所有接口禁用；</span>
                </span>
              </div>
            </template>
            <el-switch
              v-if="getYunxkCfigObj"
              v-model="getYunxkCfigObj.enabled"
              @change="changeEnabled"
            />
            <span v-if="getYunxkCfigObj?.enabled">开启</span>
            <span v-if="!getYunxkCfigObj?.enabled">关闭</span>
          </el-form-item>
          <el-form-item class="form_item" prop="path">
            <template #label>
              <div class="form_item_label">
                <span class="name">星空服务访问域名</span>
                <span class="tips">绑定星空主机上服务域名</span>
              </div>
            </template>
            <el-input
              v-model.trim="getYunxkCfigObj.path"
              :disabled="!getYunxkCfigObj.enabled"
              class="input_width"
              laceholder="请输入超管账号"
            >
              <template #prepend>
                <el-select
                  v-model="selectHttps"
                  :disabled="!getYunxkCfigObj.enabled"
                  placeholder="Select"
                  style="width: 88px"
                >
                  <el-option label="http://" value="1" />
                  <el-option label="https://" value="2" />
                </el-select>
              </template>
            </el-input>
            <HPlainButton :disabled="!getYunxkCfigObj.enabled" type="primary" @click="savePath">
              保存
            </HPlainButton>
          </el-form-item>
          <el-form-item class="form_item">
            <template #label>
              <div class="form_item_label">
                <span class="name">使用组织</span>
              </div>
            </template>
            <el-select
              v-model="getYunxkCfigObj.useOrgId"
              no-data-text="无法获取组织"
              :disabled="!getYunxkCfigObj.enabled"
              class="input_width"
              clearable
              placeholder="请选择库存组织"
            >
              <el-option
                v-for="item in getStockOrgListOp"
                :key="item.stockOrgId"
                :label="item.name"
                :value="item.stockOrgId"
                @click="
                  ;(getYunxkCfigObj.useOrg = item.name),
                    (getYunxkCfigObj.useOrgNumber = item.number)
                "
              />
            </el-select>
            <HPlainButton :disabled="!getYunxkCfigObj.enabled" type="primary" @click="saveUseOrg">
              保存
            </HPlainButton>
          </el-form-item>
          <el-form-item class="form_item">
            <template #label>
              <div class="form_item_label">
                <span class="name">星空超管账号</span>
                <span class="tips">绑定星空超管账号</span>
              </div>
            </template>
            <span class="normal_tip">
              <div v-if="!getYunxkCfigObj.appId" style="color: #999">保存域名后显示</div>
              <div v-else-if="!getYunxkCfigObj.userName" style="color: #999">保存域名后显示</div>
              <span v-else> {{ getYunxkCfigObj.userName }}</span>
            </span>
          </el-form-item>
          <!-- <el-form-item class="form_item">
                        <template #label>
                            <div class="form_item_label">
                                <span class="name">绑定账套</span>
                                <span class="tips">绑定需要同步数据的账套</span>
                            </div>
                        </template>
                        <el-select multiple collapse-tags collapse-tags-tooltip placeholder="请选择需要对接的数据账套" filterable
                            fit-input-width remote-show-suffix class="input_width">
                            <el-option label="数据" value="1" />
                        </el-select>
                    </el-form-item> -->
          <el-form-item class="form_item">
            <template #label>
              <div class="form_item_label">
                <span class="name">绑定账套ID</span>
                <span class="tips">所同步的账套ID（仅查看）</span>
              </div>
            </template>
            <div v-if="!getYunxkCfigObj.appId" style="color: #999">保存域名后显示</div>
            <div v-show="is_show1 && getYunxkCfigObj.acctId" class="normal_tip">
              <span>{{ getYunxkCfigObj.acctId }}</span>
              <el-icon @click="is_show1 = !is_show1">
                <View />
              </el-icon>
            </div>
            <div v-show="!is_show1 && getYunxkCfigObj.acctId" class="normal_tip">
              <span style="color: #999">{{ maskString(getYunxkCfigObj.acctId) }}</span>
              <el-icon @click="is_show1 = !is_show1">
                <Hide />
              </el-icon>
            </div>
          </el-form-item>
          <el-form-item class="form_item">
            <template #label>
              <div class="form_item_label">
                <span class="name">第三方系统登录授权的应用ID</span>
              </div>
            </template>
            <div v-if="!getYunxkCfigObj.appId" style="color: #999">保存域名后显示</div>
            <div v-show="is_show2 && getYunxkCfigObj.appId" class="normal_tip">
              <span>{{ getYunxkCfigObj.appId }}</span>
              <el-icon @click="is_show2 = !is_show2">
                <View />
              </el-icon>
            </div>
            <div v-show="!is_show2 && getYunxkCfigObj.appId" class="normal_tip">
              <span style="color: #999">{{ maskString(getYunxkCfigObj.appId) }}</span>
              <el-icon @click="is_show2 = !is_show2">
                <Hide />
              </el-icon>
            </div>
          </el-form-item>
          <el-form-item class="form_item">
            <template #label>
              <div class="form_item_label">
                <span class="name">第三方系统登录授权的应用密钥</span>
              </div>
            </template>
            <div v-if="!getYunxkCfigObj.appId" style="color: #999">保存域名后显示</div>
            <div v-show="is_show3 && getYunxkCfigObj.appSecret" class="normal_tip">
              <span>{{ getYunxkCfigObj.appSecret }}</span>
              <el-icon @click="is_show3 = !is_show3">
                <View />
              </el-icon>
            </div>
            <div v-show="!is_show3 && getYunxkCfigObj.appSecret" class="normal_tip">
              <span style="color: #999">{{ maskString(getYunxkCfigObj.appSecret) }}</span>
              <el-icon @click="is_show3 = !is_show3">
                <Hide />
              </el-icon>
            </div>
          </el-form-item>
          <!-- <div class="form_item_footer">
                        <HPlainButton type="primary" @click="changeacctId">绑定账号</HPlainButton>
                        <HPlainButton type="error">解除绑定</HPlainButton>
                    </div> -->
        </el-form>
        <div class="divider"></div>
        <div class="set_top_right">
          <div class="set_top_right_item">
            <div class="set_tag_item version">
              <div class="content">
                <p>版本</p>
                <p>V20240630.1.0</p>
              </div>
            </div>
            <div class="set_tag_item">
              <div class="content">
                <p>适用于</p>
                <p>金蝶云星空企业版/标准版</p>
              </div>
            </div>
          </div>
          <div class="set_top_right_item">
            <div class="set_tag_item">
              <div class="content">
                <p>配置包下载</p>
                <p class="xy_main_btn" @click="downLoad">金蝶云星空配置包</p>
              </div>
            </div>
            <div class="set_tag_item">
              <div class="content">
                <p>帮助</p>
                <p class="xy_main_btn" @click="downLoadPDF">
                  <el-icon color="#007cff">
                    <Reading />
                  </el-icon>
                  使用说明
                </p>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="mag_bg docking-list">
      <div class="title_top">对接列表</div>
      <div class="table_box">
        <el-table :border="true" height="100%" stripe resizable :data="tableDataList">
          <template #empty>
            <el-empty description="暂无数据" />
          </template>
          <!-- 序号 -->
          <el-table-column label="序号" type="index" width="50" align="center" />
          <!-- 名称 -->
          <el-table-column show-overflow-tooltip label="接口名称" prop="name" min-width="140" />
          <!-- <el-table-column show-overflow-tooltip label="接口同步情况" align="center" width="100">
                        <template v-slot="i">
                            <span style="display: flex;align-items: center;justify-content: center;">
                                <HStatus v-if="i.row.type == 3 || i.row.type == 1 || i.row.type == 7" type="warning">空闲中
                                </HStatus>
                                <HStatus v-else-if="i.row.type == 4 || i.row.type == 6">同步中</HStatus>
                                <HStatus type="info" v-else-if="i.row.type == 5">禁用</HStatus>
                                <HStatus type="error" v-else>异常</HStatus>
                            </span>
                        </template>
                    </el-table-column> -->

          <el-table-column show-overflow-tooltip label="对接方向" prop="" width="80">
            <template #default="i">
              <span v-if="[7, 8, 9].includes(i.row.type)">反写</span>
              <span v-else>同步</span>
            </template>
          </el-table-column>
          <el-table-column show-overflow-tooltip label="数据类型" prop="userName" min-width="120">
            <template #default="i">
              {{ [5, 6, 7].includes(i.row.type) ? '出库单据' : '基础资料' }}
            </template>
          </el-table-column>
          <el-table-column
            show-overflow-tooltip
            label="接口状态"
            prop="userName"
            align="center"
            width="80"
            fixed="right"
          >
            <template #default="scope">
              <span style="display: flex; align-items: center; justify-content: center">
                <HStatus v-if="scope.row.status || !getYunxkCfigObj?.enabled" type="info">
                  禁用
                </HStatus>
                <HStatus v-else>启用</HStatus>
              </span>
            </template>
          </el-table-column>
          <el-table-column fixed="right" label="操作" prop="userName" width="200">
            <template #default="i">
              <el-space :size="0" :spacer="spacer">
                <template v-if="![1, 7, 10, 11, 12, 13].includes(i.row.type)">
                  <HLink v-if="getYunxkCfigObj?.enabled" @click="popRight(i.row.type)">设置</HLink>
                  <HLink v-else disabled>设置</HLink>
                </template>
                <HLink
                  v-if="i.row.type == 2 && getYunxkCfigObj?.enabled"
                  @click="asyncTypeShow(i.row.type, 1)"
                >
                  成品同步
                </HLink>
                <HLink v-else-if="i.row.type == 2 && !getYunxkCfigObj?.enabled" disabled>
                  成品同步
                </HLink>
                <HLink
                  v-if="i.row.type == 2 && getYunxkCfigObj?.enabled"
                  @click="asyncTypeShow(i.row.type, 2)"
                >
                  物料同步
                </HLink>
                <HLink v-else-if="i.row.type == 2 && !getYunxkCfigObj?.enabled" disabled>
                  物料同步
                </HLink>
                <HLink
                  v-if="i.row.type != 7 && i.row.type != 2 && getYunxkCfigObj?.enabled"
                  @click="asyncTypeShow(i.row.type)"
                  >同步
                </HLink>
                <HLink v-else-if="i.row.type != 7 && i.row.type != 2" disabled>同步</HLink>
                <!-- <HLink type="error">禁用</HLink> -->
              </el-space>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </div>

    <!-- 同步数据弹窗 -->
    <h-dialog
      v-model="isBigAsync"
      :width="800"
      title="同步数据"
      :is-close-btn-click-hide-dialog="false"
      @close="onCloseSynchronizationDialog"
    >
      <div class="synchronization-progress-wrapper">
        <el-progress
          v-if="dataReturned ? dataReturned.end === false : true"
          :stroke-width="10"
          type="circle"
          :percentage="syncProgress"
          color="#00c0c0"
          class="synchronization-progress"
        >
          <div class="progress-content">
            <div class="num">{{ syncProgress.toFixed(2) }}%</div>
            <div class="tip">正在同步数据，请稍等...&nbsp;...</div>
          </div>
        </el-progress>
        <div
          v-if="dataReturned && dataReturned.end && msgHtml.length === 0"
          class="success-wrapper"
        >
          <div class="circle">
            <i class="iconfont icon-dagou"></i>
          </div>
          <div class="tip">数据同步成功</div>
        </div>
        <div v-if="dataReturned && dataReturned.end && msgHtml.length > 0" class="fail-wrapper">
          <div class="circle-bg">
            <div class="circle">
              <i class="iconfont icon-guanbi"></i>
            </div>
          </div>
          <div ref="msgContentBoxs" class="msg-wrapper">
            <span v-for="(item, index) in msgHtml" :key="index" v-html="item"></span>
          </div>
        </div>
      </div>

      <template #footer>
        <h-button is-modal @click="onCloseSynchronizationDialog">关闭</h-button>
      </template>
    </h-dialog>

    <h-drawer v-model="popRightDialog" :width="60" @close="onPopCancel">
      <template #title>
        <div class="title_el_dra">
          <span class="text">{{ popRightTitle }}</span>
          <i class="iconfont icon-refresh_2" @click="popRight(isType)"></i>
          <div class="tip">
            <div class="dot"></div>
            <div class="text">点击刷新</div>
          </div>
        </div>
      </template>
      <div v-loading="loading" class="pop-dialog" element-loading-text="加载中...">
        <el-form ref="formRef" label-width="auto" label-position="left">
          <el-form-item>
            <template #label>
              <span style="width: 8px; color: #f56c6c"></span>
              <span class="label_flex">
                <el-icon>
                  <Tickets />
                </el-icon>
                <span>描述</span>
              </span>
            </template>
            {{ Description_Content }}
          </el-form-item>
          <el-form-item>
            <template #label>
              <span style="width: 8px; color: #f56c6c"></span>
              <span class="label_flex">
                <el-icon>
                  <Refresh />
                </el-icon>
                {{ [7].includes(isType) ? '反写条件' : '同步条件' }}
              </span>
            </template>
            <span style="color: #007cff">{{ synchronous_Conditions }}</span>
          </el-form-item>
          <!-- 1 -->
          <template v-if="[1].includes(isType)">
            <el-form-item>
              <template #label>
                <!-- <span style="width: 8px; color: #f56c6c">*</span> -->
                <span class="label_flex">
                  <el-icon>
                    <Iphone />
                  </el-icon>
                  手机为空或不对时补充为
                </span>
              </template>
              <div class="form_item_content">
                <el-input
                  v-model.trim="YunxkUserObj.userPhone"
                  placeholder="请输入手机号前7位"
                  style="width: 50%"
                  maxlength="7"
                  @input="YunxkUserObj.userPhone = YunxkUserObj.userPhone.replace(/\D/g, '')"
                />
                <el-input style="width: 50%" placeholder="随机后四位" disabled />
              </div>
            </el-form-item>
            <el-form-item prop="userAddress">
              <template #label>
                <!-- <span style="width: 8px; color: #f56c6c">*</span> -->
                <span class="label_flex">
                  <el-icon>
                    <MapLocation />
                  </el-icon>
                  地址为空或不对时补充为
                </span>
              </template>
              <div class="form_item_content" style="align-items: flex-start">
                <SingleAddress ref="singleAddressRef" :address="address" style="width: 50%" />
                <el-input
                  v-model.trim="YunxkUserObj.userAddress"
                  style="width: 50%"
                  placeholder="详细地址"
                  clearable
                  maxlength="100"
                />
              </div>
            </el-form-item>
          </template>

          <!-- 物料信息同步 -->
          <template v-if="isType === 2">
            <el-form-item>
              <template #label>
                <span style="width: 8px; color: #f56c6c; opacity: 0">*</span>
                <span class="label_flex">
                  <el-icon>
                    <Box />
                  </el-icon>
                  无分类的物料同步为
                </span>
              </template>
              <div class="form_item_content">
                <el-select
                  v-model="goodMaterialAsyncForm.goodsTypeId"
                  style="width: 310px"
                  placeholder=""
                  filterable
                  remote
                  clearable
                  reserve-keyword
                  remote-show-suffix
                  :loading="typeLoad"
                  :remote-method="searchTypeSelect"
                >
                  <el-option
                    v-for="item in typeOptions"
                    :key="item.id"
                    :label="item.name"
                    :value="item.id"
                  />
                </el-select>
              </div>
            </el-form-item>
            <el-form-item>
              <template #label>
                <span style="width: 8px; color: #f56c6c; opacity: 0">*</span>
                <span class="label_flex">
                  <el-icon>
                    <Collection />
                  </el-icon>
                  品牌自动补充为
                </span>
              </template>
              <div class="form_item_content">
                <el-select
                  v-model="goodMaterialAsyncForm.goodsBrandId"
                  style="width: 310px"
                  placeholder="请选择品牌"
                  filterable
                  remote
                  reserve-keyword
                  clearable
                  remote-show-suffix
                  :loading="brandLoad"
                  :remote-method="searchBrandSelect"
                >
                  <el-option
                    v-for="item in brandOptions"
                    :key="item.id"
                    :label="item.name"
                    :value="item.id"
                  />
                </el-select>
              </div>
            </el-form-item>
            <el-form-item>
              <template #label>
                <span style="width: 8px; color: #f56c6c"></span>
                <span class="label_flex">
                  <el-icon>
                    <PriceTag />
                  </el-icon>
                  是否同步价格
                </span>
              </template>
              <el-switch
                v-model="goodMaterialAsyncForm.syncGoodsPrice"
                size="small"
                active-text="同步"
              />
            </el-form-item>
            <el-tabs
              v-model="goodsMaterialAsyncActiveTab"
              class="demo-tabs"
              @tab-change="onGoodsMaterialAsyncTabChange"
            >
              <el-tab-pane name="product" label="成品同步">
                <div class="product-async-wrapper">
                  <div v-if="goodMaterialTypes.length === 0" class="no-data-wrapper">
                    <div v-if="errorMsgForGetGoodTypeFail" class="main-tip">
                      <i class="iconfont icon-guanbi"></i>
                      <div class="txt">{{ errorMsgForGetGoodTypeFail }}</div>
                    </div>
                    <el-empty :image-size="250">
                      <template #description>
                        <div class="sub-tip">暂无数据</div>
                      </template>
                    </el-empty>
                  </div>
                  <template v-else>
                    <el-checkbox
                      v-model="isSelectedAllGoodProductMaterialType"
                      :indeterminate="isGoodProductMaterialTypeAllSelectHalf"
                      @change="onSelectAllGoodMaterialType('product')"
                      >全选</el-checkbox
                    >
                    <el-tree
                      ref="goodProductMaterialAsyncTreeInstance"
                      :data="goodMaterialTypes"
                      show-checkbox
                      node-key="id"
                      :props="goodMaterialAsyncTreeProps"
                      @check="handleGoodMaterialTypeSelect('product')"
                    ></el-tree>
                  </template>
                </div>
              </el-tab-pane>
              <el-tab-pane name="part" label="物料同步">
                <div class="part-async-wrapper">
                  <div v-if="goodMaterialTypes.length === 0" class="no-data-wrapper">
                    <div v-if="errorMsgForGetGoodTypeFail" class="main-tip">
                      <i class="iconfont icon-guanbi"></i>
                      <div class="txt">{{ errorMsgForGetGoodTypeFail }}</div>
                    </div>
                    <el-empty :image-size="250">
                      <template #description>
                        <div class="sub-tip">暂无数据</div>
                      </template>
                    </el-empty>
                  </div>
                  <template v-else>
                    <el-checkbox
                      v-model="isSelectedAllGoodPartMaterialType"
                      :indeterminate="isGoodPartMaterialTypeAllSelectHalf"
                      @change="onSelectAllGoodMaterialType('part')"
                      >全选</el-checkbox
                    >
                    <el-tree
                      ref="goodPartMaterialAsyncTreeInstance"
                      :data="goodMaterialTypes"
                      show-checkbox
                      node-key="id"
                      :props="goodMaterialAsyncTreeProps"
                      @check="handleGoodMaterialTypeSelect('part')"
                    ></el-tree>
                  </template>
                </div>
              </el-tab-pane>
            </el-tabs>
          </template>

          <!-- 3 -->
          <template v-if="[3, 4].includes(isType)">
            <el-form-item>
              <template #label>
                <span style="width: 8px; color: #f56c6c"></span>
                <span class="label_flex">
                  <el-icon>
                    <Iphone />
                  </el-icon>
                  手机为空或不对时补充为
                </span>
              </template>
              <div class="form_item_content">
                <el-input
                  v-model.trim="YunxkStoreCfig.storePhone"
                  placeholder="请输入手机号前7位"
                  style="width: 50%"
                  maxlength="7"
                  @input="YunxkStoreCfig.storePhone = YunxkStoreCfig.storePhone.replace(/\D/g, '')"
                />
                <el-input style="width: 50%" placeholder="随机后四位" disabled />
              </div>
            </el-form-item>
            <el-form-item>
              <template #label>
                <span style="width: 8px; color: #f56c6c; opacity: 0">*</span>
                <span class="label_flex">
                  <el-icon>
                    <MapLocation />
                  </el-icon>
                  地址为空或不对时补充为
                </span>
              </template>
              <div class="form_item_content">
                <SingleAddress ref="singleAddressRef" :address="address" style="width: 50%" />
                <el-input
                  v-model.trim="YunxkStoreCfig.storeAddress"
                  style="width: 50%"
                  placeholder="详细地址"
                  maxlength="100"
                />
              </div>
            </el-form-item>
            <!-- <el-form-item>
              <template #label>
                <span style="width: 8px; color: #f56c6c"></span>
                <span class="label_flex">
                  <el-icon>
                    <PriceTag />
                  </el-icon>
                  是否同步库存
                </span>
              </template>
              <el-switch v-model="YunxkStoreCfig.syncStoreStock" size="small" active-text="同步" />
            </el-form-item> -->
          </template>
          <!-- 6 -->
          <template v-if="[6].includes(isType)">
            <!-- <el-form-item>
                            <template #label>
                                <span class="label_flex"><el-icon>
                                        <SoldOut />
                                    </el-icon>出库单类型同步为</span>
                            </template>
      <div class="form_item_content"> <el-select style="width: 310px;" placeholder="若不选，则默认为“销售出库”类型"></el-select>
      </div>
      </el-form-item> -->
            <el-form-item>
              <template #label>
                <span style="width: 8px; color: #f56c6c"></span>
                <span class="label_flex">
                  <el-icon>
                    <PriceTag />
                  </el-icon>
                  是否同步价格
                </span>
              </template>
              <el-switch
                v-model="storeCfigVo.syncSaleOutStorePrice"
                size="small"
                active-text="同步"
              />
            </el-form-item>
          </template>
          <!-- 7 -->
          <template v-if="[7].includes(isType)">
            <el-form-item>
              <template #label>
                <span style="width: 8px; color: #f56c6c">*</span>
                <span class="label_flex">
                  <el-icon>
                    <SoldOut />
                  </el-icon>
                  出库单类型反写为
                </span>
              </template>
              <div class="form_item_content">
                <el-select
                  v-model="reverseWritingCfigVo.otherStoreBillTypeId"
                  style="width: 310px"
                  placeholder="若不选，则默认为“销售出库”类型"
                  clearable
                >
                  <template #header>
                    <div style="display: flex; gap: 10px; align-items: flex-end">
                      <div style="display: flex; flex-direction: column; gap: 10px; width: 160px">
                        <el-input
                          v-model.trim="outStoreData.name"
                          clearable
                          placeholder="单据类型名称"
                          @keyup.enter="getOtherOutStoreBillTypeFun"
                          @clear="getOtherOutStoreBillTypeFun"
                        />
                        <el-input
                          v-model.trim="outStoreData.number"
                          clearable
                          placeholder="单据类型条码"
                          @keyup.enter="getOtherOutStoreBillTypeFun"
                          @clear="getOtherOutStoreBillTypeFun"
                        />
                      </div>
                      <HPlainButton @click="getOtherOutStoreBillTypeFun">搜索</HPlainButton>
                    </div>
                  </template>
                  <el-option
                    v-for="item in OtherOutStoreBillType"
                    :key="item.id"
                    :label="item.name"
                    :value="item.id"
                    @click="
                      ;(reverseWritingCfigVo.otherStoreBillType = item.name),
                        (reverseWritingCfigVo.otherStoreBillTypeNumber = item.number)
                    "
                  >
                    <span style="float: left">{{ item.name }}</span>
                    <span style="float: right">
                      {{ item.number }}
                    </span>
                  </el-option>
                </el-select>
              </div>
            </el-form-item>
            <el-form-item>
              <template #label>
                <span style="width: 8px; color: #f56c6c">*</span>
                <span class="label_flex">
                  <el-icon>
                    <SoldOut />
                  </el-icon>
                  出库公司若为空时补充为
                </span>
              </template>
              <div class="form_item_content">
                <el-select
                  v-model="reverseWritingCfigVo.otherStoreCustId"
                  style="width: 310px"
                  placeholder="请选择公司下拉"
                  clearable
                >
                  <template #header>
                    <div style="display: flex; gap: 10px; align-items: flex-end">
                      <div style="display: flex; flex-direction: column; gap: 10px; width: 160px">
                        <el-input
                          v-model.trim="getUserData.name"
                          clearable
                          placeholder="公司名称"
                          @keyup.enter="getUserFun"
                          @clear="getUserFun"
                        />
                        <el-input
                          v-model.trim="getUserData.number"
                          clearable
                          placeholder="公司条码"
                          @keyup.enter="getUserFun"
                          @clear="getUserFun"
                        />
                      </div>
                      <HPlainButton @click="getUserFun">搜索</HPlainButton>
                    </div>
                  </template>
                  <el-option
                    v-for="item in getUserObj"
                    :key="item.id"
                    :label="item.fname"
                    :value="item.id"
                    @click="
                      ;(reverseWritingCfigVo.otherStoreCust = item.fname),
                        (reverseWritingCfigVo.otherStoreCustNumber = item.fnumber)
                    "
                  >
                    <span style="float: left">{{ item.fname }}</span>
                    <span style="float: right">{{ item.fnumber }}</span>
                  </el-option>
                </el-select>
              </div>
            </el-form-item>
            <el-form-item>
              <template #label>
                <span style="width: 8px; color: #f56c6c">*</span>
                <span class="label_flex">
                  <el-icon>
                    <SoldOut />
                  </el-icon>
                  反写到星空的库存状态为
                </span>
              </template>
              <div class="form_item_content">
                <el-select
                  v-model="reverseWritingCfigVo.otherStoreStockStatusId"
                  style="width: 310px"
                  placeholder="请选择星空的库存状态"
                  clearable
                >
                  <el-option
                    v-for="item in getStoreStockStatusObj"
                    :key="item.id"
                    :label="item.fname"
                    :value="item.id"
                    @click="
                      ;(reverseWritingCfigVo.otherStoreStockStatus = item.fname),
                        (reverseWritingCfigVo.otherStoreStockStatusNumber = item.fnumber)
                    "
                  >
                    <span style="float: left">{{ item.fname }}</span>
                    <span style="float: right">{{ item.fnumber }}</span>
                  </el-option>
                </el-select>
              </div>
            </el-form-item>
            <el-form-item>
              <template #label>
                <span style="width: 8px; color: #f56c6c"></span>
                <span class="label_flex">
                  <el-icon>
                    <SoldOut />
                  </el-icon>
                  反写到星空的单据状态为
                </span>
              </template>
              <div class="form_item_content">
                <el-select
                  v-model="reverseWritingCfigVo.otherStoreBillStatus"
                  disabled
                  style="width: 310px"
                  placeholder="请选择星空的单据状态"
                >
                  <el-option
                    v-for="item in orderStatus"
                    :key="item.value"
                    :label="item.name"
                    :value="item.value"
                  />
                </el-select>
              </div>
            </el-form-item>
            <!-- <el-form-item>
                            <template #label>
                                <span class="label_flex"><el-icon>
                                        <SoldOut />
                                    </el-icon>反写到星空的库存组织为</span>
                            </template>
                            <div class="form_item_content"> <el-select style="width: 310px;"
                                    v-model="reverseWritingCfigVo.stockOrgId" placeholder="请选择库存组织">
                                    <el-option
                                        @click="reverseWritingCfigVo.stockOrgName = item.name, reverseWritingCfigVo.stockOrgNumber = item.number"
                                        v-for="item in getStockOrgListOp" :key="item.stockOrgId" :label="item.name"
                                        :value="item.stockOrgId"><span style="float: left">{{ item.name }}</span><span
                                            style="float: right;">{{ item.number }}</span></el-option></el-select>
                            </div>
                        </el-form-item> -->

            <el-form-item>
              <template #label>
                <span style="width: 8px; color: #f56c6c"></span>
                <span class="label_flex">
                  <el-icon>
                    <PriceTag />
                  </el-icon>
                  是否反写价格
                </span>
              </template>
              <el-switch
                v-model="reverseWritingCfigVo.syncOtherStoreGoodsPrice"
                size="small"
                active-text="反写"
              />
            </el-form-item>
          </template>
          <template v-if="[8].includes(isType)">
            <el-form-item>
              <template #label>
                <span class="label_flex">
                  <el-icon>
                    <SoldOut />
                  </el-icon>
                  出库单类型同步为
                </span>
              </template>
              <div class="form_item_content">
                <el-select style="width: 310px" placeholder="若不选，则默认为“销售出库”类型" />
              </div>
            </el-form-item>
            <el-form-item>
              <template #label>
                <span class="label_flex">
                  <el-icon>
                    <PriceTag />
                  </el-icon>
                  是否同步价格
                </span>
              </template>
              <el-switch size="small" active-text="同步" />
            </el-form-item>
          </template>
          <el-form-item v-if="[9].includes(isType)">
            <template #label>
              <span class="label_flex">
                <el-icon>
                  <SoldOut />
                </el-icon>
                出库单类型同步为
              </span>
            </template>
            <div class="form_item_content">
              <el-select style="width: 310px" placeholder="若不选，则默认为“销售出库”类型" />
            </div>
          </el-form-item>
          <el-form-item v-if="[9].includes(isType)">
            <template #label>
              <span class="label_flex">
                <el-icon>
                  <PriceTag />
                </el-icon>
                是否同步价格
              </span>
            </template>
            <el-switch size="small" active-text="同步" />
          </el-form-item>
        </el-form>

        <!-- 同步数据弹窗 -->
        <h-dialog
          v-if="dataReturned"
          v-model="isMinAsync"
          :width="800"
          title="同步数据"
          :is-close-btn-click-hide-dialog="false"
          @close="onCloseSynchronizationDialog"
        >
          <div class="synchronization-progress-wrapper">
            <el-progress
              v-if="dataReturned ? dataReturned.end === false : true"
              :stroke-width="10"
              type="circle"
              :percentage="syncProgress"
              color="#00c0c0"
              class="synchronization-progress"
            >
              <div class="progress-content">
                <div class="num"> {{ syncProgress.toFixed(2) }}% </div>
                <div class="tip">正在同步数据，请稍等...&nbsp;...</div>
              </div>
            </el-progress>
            <div
              v-if="dataReturned && dataReturned.end && msgHtml.length === 0"
              class="success-wrapper"
            >
              <div class="circle">
                <i class="iconfont icon-dagou"></i>
              </div>
              <div class="tip">数据同步成功</div>
            </div>
            <div v-if="dataReturned && dataReturned.end && msgHtml.length > 0" class="fail-wrapper">
              <div class="circle-bg">
                <div class="circle">
                  <i class="iconfont icon-guanbi"></i>
                </div>
              </div>
              <div ref="msgContentBoxs" class="msg-wrapper">
                <span v-for="(item, index) in msgHtml" :key="index" v-html="item"></span>
              </div>
            </div>
          </div>

          <template #footer>
            <h-button is-modal @click="onCloseSynchronizationDialog">关闭</h-button>
          </template>
        </h-dialog>
      </div>
      <template #footer>
        <div style="display: flex; justify-content: flex-end; gap: 10px">
          <HButton v-if="![7].includes(isType)" type="primary" is-modal @click="saveAsyncCommit">
            保存并同步
          </HButton>
          <HPlainButton v-if="![5].includes(isType)" is-modal @click="saveCommit">
            保存设置
          </HPlainButton>
          <HButton is-modal @click="onPopCancel()">关闭</HButton>
        </div>
      </template>
    </h-drawer>
  </div>
</template>

<script setup lang="ts">
  import { ref, h, onMounted, watch, nextTick } from 'vue'
  import { ElDivider, ElMessage, ElMessageBox, TreeInstance } from 'element-plus'
  import { initWebSocket, closeWebSocket } from '@/utils/socket'
  import {
    Box,
    Collection,
    Hide,
    Iphone,
    MapLocation,
    PriceTag,
    Reading,
    Refresh,
    SoldOut,
    Tickets,
    View,
  } from '@element-plus/icons-vue'
  import _ from 'lodash'
  import SingleAddress from '@/components/address/singleAddress.vue'
  import {
    getYunxkCfig,
    getYunxkUserCfig,
    saveUserCfig,
    saveWithSyncUserCfig,
    getGoodsTypeList,
    getGoodsCfig,
    saveGoodsCfig,
    saveSyncGoods,
    getYunxkStoreCfig,
    saveStoreCfig,
    saveSyncStore,
    saveSyncOtherStore,
    syncGoods,
    syncStore,
    syncUserCfig,
    saveSyncYunxkSaleStore,
    saveYunxkSaleStoreCfig,
    syncYunxkSaleStore,
    syncOtherStore,
    getOrgList,
    getOtherOutStoreBillType,
    getUser,
    getStoreStockStatus,
    getOtherOutStoreReverseWriting,
    saveOtherOutStoreCfig,
    saveYunxkEnableCfig,
    saveYunxkPathCfig,
    saveYunxkOrgCfig,
    saveAsyncSnCode,
    syncWarehouseStock,
    syncMountings,
    productSyncData,
  } from '@/api/application'
  import { brandPageSelect, typePageSelect } from '@/api/goodsInfo'
  import routeComponentName from '@/config/route-component-name'
  import { HMessageBox } from '@/components/common/message'

  defineOptions({
    name: routeComponentName.appCenter.kingdeeXingkongConnectConfig,
  })

  // 产品物料同步树形组件配置
  const goodMaterialAsyncTreeProps = ref({
    children: 'childData',
    label: 'name',
    disabled: 'disabledSelect',
  })

  // 是否选择了全部的成品物料分类
  const isSelectedAllGoodProductMaterialType = ref(false)

  // 是否选择了全部的物料物料分类
  const isSelectedAllGoodPartMaterialType = ref(false)

  // 产品物料分类同步树形组件实例
  const goodProductMaterialAsyncTreeInstance = ref<TreeInstance | null>(null)

  // 物料物料分类同步树形组件实例
  const goodPartMaterialAsyncTreeInstance = ref<TreeInstance | null>(null)

  // 产品物料分类全选是否半选
  const isGoodProductMaterialTypeAllSelectHalf = ref(false)

  // 物料物料分类全选是否半选
  const isGoodPartMaterialTypeAllSelectHalf = ref(false)

  // 间距组件的间隔符
  const spacer = h(ElDivider, {
    direction: 'vertical',
    style: 'display: flex; align-items: center;',
  })
  const selectHttps = ref('1')
  const tableDataList = ref([
    { name: '公司信息接口', type: 1 },
    { name: '物料信息接口', type: 2 },
    { name: '仓库信息接口', type: 3 },
    { name: '仓库库存接口', type: 11 },
    // { name: '装配清单接口', type: 12 },
    // { name: '物料库存同步', type: 4 },
    // { name: '其他出库单同步', type: 5 },
    { name: '销售出库单接口', type: 6 },
    { name: '售后  物料出库单 >-其他出库单', type: 7 },
    // { name: '售后  结算付款单 >-星空  应付单', type: 8 },
    // { name: '售后  结算付款单 >-星空  应收单', type: 9 },
    { name: '条码档案（星空）>- 条码库（售后）', type: 10 },
    { name: 'BOM 同步', type: 13 },
  ])
  /**
   * 单据状态：Z：暂存，A：保存，B：审核中，C：已审核
   */
  const orderStatus = ref([
    { name: '暂存', value: 'Z' },
    { name: '保存', value: 'A' },
    { name: '审核中', value: 'B' },
    { name: '已审核', value: 'C' },
  ])

  // 产品物料同步表单
  const goodMaterialAsyncForm = ref<XingKongApiRequest.GoodMaterialAsync>({
    goodsBrandId: '',
    goodsType: 1,
    goodsTypeId: '',
    goodsTypeVos: [],
    syncGoodsPrice: true,
  })

  const YunxkStoreCfig = ref({
    storeAddress: '',
    storeArea: '',
    storeCity: '',
    storePhone: '', //仓库负责人手机号前七位
    storeProvince: '',
    syncStoreStock: false, //是否同步库存：false-关闭，true-开启,示例值(true)
  })
  const storeCfigVo = ref({
    syncSaleOutStorePrice: true,
  })

  const leftObj = ref({
    checkAll: false,
    isIndeterminate: false,
    leftChack: [],
  })
  const rightObj = ref({
    checkAllright: false,
    isIndeterminateright: false,
    rightChack: [],
    page: 1,
  })
  const arrTypeIds = ref([])

  const is_show1 = ref(false)
  const is_show2 = ref(false)
  const is_show3 = ref(false)
  // 弹窗显示
  const popRightDialog = ref(false)
  const popRightTitle = ref('') //弹窗标题
  const Description_Content = ref('') //描述
  const synchronous_Conditions = ref('') //同步条件

  // 产品物料同步选中的标签名
  const goodsMaterialAsyncActiveTab = ref<'part' | 'product'>('product')

  const loading = ref(false)
  const maskString = (str) => {
    if (!str) return
    var start = str.slice(0, 4)
    var end = str.slice(-4)
    var masked = start + '*'.repeat(6) + end
    return masked
  }

  /**
   * 产品物料同步弹窗的标签切换事件
   */
  const onGoodsMaterialAsyncTabChange = () => {
    goodMaterialAsyncForm.value.goodsTypeVos = []
    leftObj.value = {
      checkAll: false,
      isIndeterminate: false,
      leftChack: [],
    }
    rightObj.value = {
      checkAllright: false,
      isIndeterminateright: false,
      rightChack: [],
      page: 1,
    }
    loading.value = true
    Promise.all([getGoodMaterialConfig(), getGoodMaterialTypes()]).then(() => {
      loading.value = false
    })
  }

  const isType = ref(0)
  const popRight = async (type) => {
    popRightDialog.value = true
    isType.value = type
    dataReturned.value = null
    msgHtml.value = []
    closeWebSocket()
    isBigAsync.value = false
    isMinAsync.value = false
    switch (type) {
      case 1:
        loading.value = true
        await getYunxkUserCfigInfo()
        loading.value = false
        popRightTitle.value = '公司信息同步设置'
        Description_Content.value = '金蝶云星空公司资料 → 售后系统公司档案'
        synchronous_Conditions.value = '公司状态为已启用的'
        break
      case 2:
        goodMaterialAsyncForm.value = {
          goodsBrandId: '',
          goodsType: 1,
          goodsTypeId: '',
          goodsTypeVos: [],
          syncGoodsPrice: true,
        }
        goodsMaterialAsyncActiveTab.value = 'product'
        // valueSele.value = []
        leftObj.value = {
          checkAll: false,
          isIndeterminate: false,
          leftChack: [],
        }
        rightObj.value = {
          checkAllright: false,
          isIndeterminateright: false,
          rightChack: [],
          page: 1,
        }
        loading.value = true
        await getGoodMaterialTypes()
        await getGoodMaterialConfig()
        await getTypeOptions('')
        await getBrandOptions('')
        loading.value = false

        popRightTitle.value = '物料信息同步设置'
        Description_Content.value = '金蝶云星空物料资料 → 售后系统产品档案'
        synchronous_Conditions.value = '物料状态为已启用的'
        break
      case 3:
      case 4:
        loading.value = true
        await getYunxkStoreCfigInfo()
        loading.value = false
        popRightTitle.value = '仓库信息同步设置'
        Description_Content.value = '金蝶云星空仓库 → 售后系统仓库管理'
        synchronous_Conditions.value = '仓库状态为已启用的'
        break
      case 5:
        popRightTitle.value = '其他出库单同步设置'
        Description_Content.value = '金蝶云星空其他出库单 → 售后系统出库单'
        synchronous_Conditions.value = '单据是“已审核”的状态'
        break
      case 6:
        storeCfigVo.value.syncSaleOutStorePrice = true
        popRightTitle.value = '销售出库单同步设置'
        Description_Content.value = '金蝶云星空销售出库单 → 售后系统出库单'
        synchronous_Conditions.value = '单据是“已审核”的状态'
        break
      case 7:
        loading.value = true
        Promise.all([
          getOtherOutStoreReverseWritingFun(),
          getOtherOutStoreBillTypeFun(),
          getUserFun(),
          getStockOrgListFun(),
          getStoreStockStatusFun(),
        ]).finally(() => {
          loading.value = false
        })
        popRightTitle.value = '物料出库单反写设置'
        Description_Content.value = '售后系统物料出库单→ 金蝶云星空其他出库单'
        synchronous_Conditions.value = '单据是“已审核”的状态'
        break
      case 8:
        popRightTitle.value = '结算付款单反写设置'
        Description_Content.value = '售后系统付款单→ 金蝶云星空其他付款单'
        synchronous_Conditions.value = '单据是“已审核”的状态'
        break
      case 9:
        popRightTitle.value = '结算收款单反写设置'
        Description_Content.value = '售后系统收款单→ 金蝶云星空其他收款单'
        synchronous_Conditions.value = '单据是“已审核”的状态'
        break
    }
  }
  // 获取其他出库单的单据类型
  const OtherOutStoreBillType = ref([])
  const outStoreData = ref({
    number: '',
    name: '',
  })
  const getOtherOutStoreBillTypeFun = _.debounce(() => {
    getOtherOutStoreBillType(outStoreData.value).then((res) => {
      if (res.data.code === 20000) {
        OtherOutStoreBillType.value = res.data.data.rows
      } else {
        HMessageBox.error(res.data.message)
      }
    })
  }, 200)
  const getStockOrgListOp = ref([])
  const getStockOrgListFun = async () => {
    const res = await getOrgList()
    if (res.data.code === 20000) {
      getStockOrgListOp.value = res.data.data.rows.map((o) => {
        o.stockOrgId = JSON.stringify(o.stockOrgId)
        return o
      })
    } else {
      HMessageBox.error(res.data.message)
    }
  }
  // 公司数据
  const getUserObj = ref([])
  const getUserData = ref({
    number: '',
    name: '',
  })
  const getUserFun = () => {
    getUser(getUserData.value).then((res) => {
      if (res.data.code === 20000) {
        getUserObj.value = res.data.data.rows.map((o) => {
          o.id = JSON.stringify(o.id)
          return o
        })
      } else {
        HMessageBox.error(res.data.message)
      }
    })
  }
  const reverseWritingCfigVo = ref({
    otherStoreBillStatus: 'Z', //反写星空其他出库单的单据状态：Z：暂存，A：保存，B：审核中，C：已审核,示例值(A)
    otherStoreBillType: '', //反写星空其他出库单单据类型名称
    otherStoreBillTypeId: '', //反写星空其他出库单单据类型ID
    otherStoreBillTypeNumber: '', //反写星空其他出库单单据类型条码
    otherStoreCust: '', //反写星空其他出库单的公司名称
    otherStoreCustId: '', //反写星空其他出库单的公司ID
    otherStoreCustNumber: '', //反写星空其他出库单的公司条码
    otherStoreStockStatus: '', //反写星空其他出库单的库存状态名称
    otherStoreStockStatusId: '', //反写星空其他出库单的库存状态ID
    otherStoreStockStatusNumber: '', //反写星空其他出库单的库存状态条码
    syncOtherStoreGoodsPrice: true, //是否同步反写星空其他出库单价格：false-关闭，true-开启,示例值(true)
    // "stockOrgId": "",
    // "stockOrgName": "",
    // "stockOrgNumber": "",
  })
  const getOtherOutStoreReverseWritingFun = async () => {
    await getOtherOutStoreReverseWriting().then((res) => {
      if (res.data.code === 20000) {
        reverseWritingCfigVo.value = res.data.data.row
        reverseWritingCfigVo.value.otherStoreBillStatus =
          res.data.data.row.otherStoreBillStatus || 'Z'
      } else {
        HMessageBox.error(res.data.message)
      }
    })
  }
  // 库存状态
  const getStoreStockStatusObj = ref([])
  const getStoreStockStatusFun = () => {
    getStoreStockStatus().then((res) => {
      if (res.data.code === 20000) {
        getStoreStockStatusObj.value = res.data.data.rows.map((o) => {
          o.id = JSON.stringify(o.id)
          return o
        })
      } else {
        HMessageBox.error(res.data.message)
      }
    })
  }

  /**
   * 获取金蝶云星空配置信息
   */
  const getYunxkCfigObj = ref({
    id: '',
    enabled: true,
    path: '',
    serverUrl: '',
    userName: '',
    acctId: '',
    appId: '',
    appSecret: '',
    useOrg: '',
    useOrgId: '',
    useOrgNumber: '',
  })
  const getYunxkCfigInfo = async () => {
    await getYunxkCfig().then((res) => {
      if (res.data.code == 20000) {
        getYunxkCfigObj.value = res.data.data.row
        selectHttps.value = res.data.data.row.path
          ? res.data.data.row.path.startsWith('https://')
            ? '2'
            : '1'
          : '1'
        getYunxkCfigObj.value.path = res.data.data.row.path
          ? res.data.data.row.path.replace(/^(https?:\/\/)/i, '')
          : ''
      } else {
        HMessageBox.error(res.data.message)
      }
    })
  }
  // 产品品牌下拉相关
  const brandOptions = ref([])
  const brandLoad = ref(false)
  const brandVal = ref('')
  // 获取产品品牌下拉
  const getBrandOptions = async (name) => {
    const data = {
      limit: 0,
      name: name,
      page: 0,
    }
    await brandPageSelect(data).then((res) => {
      brandOptions.value = res.data.data.rows
    })
  }
  // 搜索产品品牌下拉
  const searchBrandSelect = (query) => {
    brandVal.value = query
    if (query) {
      brandLoad.value = true
      setTimeout(async () => {
        brandLoad.value = false
      }, 1000)
    }
  }
  watch(
    () => brandVal.value,
    (newVal) => {
      if (newVal != '') {
        getBrandOptions(newVal)
      } else {
        getBrandOptions('')
      }
    },
  )
  // 搜索产品分类下拉
  const typeVal = ref('')
  const typeLoad = ref(false)
  const searchTypeSelect = (query) => {
    typeVal.value = query
    if (query) {
      typeLoad.value = true
      setTimeout(async () => {
        typeLoad.value = false
      }, 1000)
    }
  }

  // 产品物料分类列表
  const goodMaterialTypes = ref<Array<XingKongGoodMaterialTypes>>([])

  // 获取产品分类失败时的错误信息，用在界面显示，提示用户
  const errorMsgForGetGoodTypeFail = ref('')

  /**
   * 选择所有的产品物料分类
   */
  const onSelectAllGoodMaterialType = (type: 'product' | 'part') => {
    let isSelectAll = isSelectedAllGoodProductMaterialType.value
    if (type === 'part') {
      isSelectAll = isSelectedAllGoodPartMaterialType.value
    }
    let treeInstance = goodProductMaterialAsyncTreeInstance.value
    if (type === 'product') {
      treeInstance = goodProductMaterialAsyncTreeInstance.value
    }
    if (treeInstance) {
      if (isSelectAll) {
        const allIds = goodMaterialTypes.value
          .filter((type) => !type.disabledSelect)
          .map((type) => type.id)
        treeInstance.setCheckedKeys(allIds)
      } else {
        treeInstance.setCheckedKeys([])
      }
      handleGoodMaterialTypeSelect(type)
    }
  }

  /**
   * 成品物料分类选择事件
   */
  const handleGoodMaterialTypeSelect = (type: 'product' | 'part') => {
    let treeInstance = goodProductMaterialAsyncTreeInstance.value
    if (type === 'part') {
      treeInstance = goodPartMaterialAsyncTreeInstance.value
    }
    if (treeInstance) {
      const types = treeInstance.getCheckedNodes() as Array<XingKongGoodMaterialTypes>
      goodMaterialAsyncForm.value.goodsTypeVos = types.map((type) => {
        if (type.level === 1) {
          return {
            type: type.name,
            typeId: String(type.id),
            twoType: '',
            twoTypeId: '',
            threeType: '',
            threeTypeId: '',
          }
        }

        if (type.level === 2) {
          const oneType = goodMaterialTypes.value.find((item) => item.id === type.parentId)

          return {
            type: oneType.name,
            typeId: String(oneType.id),
            twoType: type.name,
            twoTypeId: String(type.id),
            threeType: '',
            threeTypeId: '',
          }
        }

        if (type.level === 3) {
          let oneType = ''
          let oneTypeId = ''
          let twoType = ''
          let twoTypeId = ''
          goodMaterialTypes.value.forEach((item) => {
            item.childData.forEach((itemChildData) => {
              if (itemChildData.id === type.parentId) {
                twoType = itemChildData.name
                twoTypeId = String(itemChildData.id)
                oneType = item.name
                oneTypeId = String(item.id)
              }
            })
          })
          return {
            type: oneType,
            typeId: oneTypeId,
            twoType: twoType,
            twoTypeId: twoTypeId,
            threeType: type.name,
            threeTypeId: String(type.id),
          }
        }
      })

      const oneTypeIds = new Set(
        goodMaterialAsyncForm.value.goodsTypeVos
          .filter((item) => !!item.type)
          .map((item) => item.typeId),
      )
      if (oneTypeIds.size === 0) {
        if (type === 'product') {
          isSelectedAllGoodProductMaterialType.value = false
        } else {
          isSelectedAllGoodPartMaterialType.value = false
        }
      }
      if (oneTypeIds.size === goodMaterialTypes.value.length) {
        if (type === 'product') {
          isSelectedAllGoodProductMaterialType.value = true
        } else {
          isSelectedAllGoodPartMaterialType.value = true
        }
      }

      if (oneTypeIds.size > 0 && oneTypeIds.size < goodMaterialTypes.value.length) {
        if (type === 'product') {
          isSelectedAllGoodProductMaterialType.value = false
          isGoodProductMaterialTypeAllSelectHalf.value = true
        } else {
          isSelectedAllGoodPartMaterialType.value = false
          isGoodPartMaterialTypeAllSelectHalf.value = true
        }
      } else {
        if (type === 'product') {
          isGoodProductMaterialTypeAllSelectHalf.value = false
        } else {
          isGoodPartMaterialTypeAllSelectHalf.value = false
        }
      }
    }
  }

  /**
   * 获取产品物料分类
   * @param page - 页码
   */
  const getGoodMaterialTypes = async () => {
    const res = await getGoodsTypeList(goodsMaterialAsyncActiveTab.value === 'product' ? 1 : 2)
    if (res.data.code === 20000) {
      goodMaterialTypes.value = res.data.data.rows
    } else {
      errorMsgForGetGoodTypeFail.value = res.data.message
      if (res.data.message.includes('公司端未登录')) {
        errorMsgForGetGoodTypeFail.value = '接口中断，请到用友U8公司端登录后再继续操作！'
      }

      if (res.data.message.includes('没有找到from_account（调用方ID）对应的用户')) {
        errorMsgForGetGoodTypeFail.value = '接口中断，调用方ID不正确，请检查后再同步'
      }

      if (res.data.message.includes('没有找到to_account对应的目标企业')) {
        errorMsgForGetGoodTypeFail.value = '接口中断，提供方ID不正确，请检查后再同步'
      }

      if (res.data.message.includes('请录入合法token')) {
        errorMsgForGetGoodTypeFail.value = '接口中断，应用条码不正确，请检查后再同步'
      }
    }
  }
  // const changeSelectList = (val, o, v) => {
  //   if (o == 'right') {
  //     goodMaterialTypes.value.filter((o) => {
  //       if (v.includes(o.id)) {
  //         goodMaterialAsyncForm.value.goodsTypeVos.push({ typeId: o.id, type: o.name })
  //       }
  //     })
  //   } else {
  //     goodMaterialAsyncForm.value.goodsTypeVos = goodMaterialAsyncForm.value.goodsTypeVos.filter(
  //       (o) => !v.includes(o.typeId),
  //     )
  //   }
  // }
  const YunxkUserObj = ref({
    id: '',
    userPhone: '',
    userProvince: '',
    userCity: '',
    userArea: '',
    userAddress: '',
    useOrg: '',
    useOrgId: '',
  })
  const address = ref({
    province: '',
    city: '',
    area: '',
    town: '',
  })
  const singleAddressRef = ref()

  /**
   * 获取金蝶云星空公司配置
   */
  const getYunxkUserCfigInfo = async () => {
    const res = await getYunxkUserCfig()
    if (res.data.code == 20000) {
      YunxkUserObj.value = res.data.data.row
      address.value = {
        province: YunxkUserObj.value.userProvince,
        city: YunxkUserObj.value.userCity,
        area: YunxkUserObj.value.userArea,
        town: '',
      }
      // const typeRes = await typePageSelect({
      //   id:
      // })
    } else {
      ElMessageBox({
        message: res.data.message,
        type: 'error',
        title: '提示',
        autofocus: false,
      })
    }
  }

  /**
   * 获取产品物料配置
   */
  const getGoodMaterialConfig = async () => {
    const res = await getGoodsCfig(goodsMaterialAsyncActiveTab.value === 'product' ? 1 : 2)
    if (res.data.code === 20000) {
      goodMaterialAsyncForm.value = res.data.data.row

      arrTypeIds.value = goodMaterialAsyncForm.value.goodsTypeVos.map((o) => o.typeId)
      nextTick(() => {
        let treeInstance = goodProductMaterialAsyncTreeInstance.value
        if (goodsMaterialAsyncActiveTab.value === 'part') {
          treeInstance = goodPartMaterialAsyncTreeInstance.value
        }
        if (treeInstance) {
          const threeTypeIds = goodMaterialAsyncForm.value.goodsTypeVos.map(
            (item) => item.threeTypeId,
          )
          const twoTypeIds = goodMaterialAsyncForm.value.goodsTypeVos.map((item) => item.twoTypeId)
          const oneTypeIds = goodMaterialAsyncForm.value.goodsTypeVos.map((item) => item.typeId)
          const checkedIds: Array<number> = []
          goodMaterialTypes.value.forEach((oneType) => {
            if (oneType.childData.length === 0 && oneTypeIds.includes(String(oneType.id))) {
              checkedIds.push(oneType.id)
            }

            oneType.childData.forEach((twoType) => {
              if (twoType.childData.length === 0 && twoTypeIds.includes(String(twoType.id))) {
                checkedIds.push(twoType.id)
              }

              twoType.childData.forEach((threeType) => {
                if (threeTypeIds.includes(String(threeType.id))) {
                  checkedIds.push(threeType.id)
                }
              })
            })
          })
          treeInstance.setCheckedKeys(checkedIds)
          handleGoodMaterialTypeSelect(goodsMaterialAsyncActiveTab.value)
        }
      })
    } else {
      HMessageBox.error(res.data.message)
    }
  }

  // 3
  const getYunxkStoreCfigInfo = async () => {
    await getYunxkStoreCfig().then((res) => {
      if (res.data.code == 20000) {
        YunxkStoreCfig.value = res.data.data.row
        address.value = {
          province: YunxkStoreCfig.value.storeProvince,
          city: YunxkStoreCfig.value.storeCity,
          area: YunxkStoreCfig.value.storeArea,
          town: '',
        }
      } else {
        ElMessageBox({
          message: res.data.message,
          type: 'error',
          title: '提示',
          autofocus: false,
        })
      }
    })
  }
  // 保存设置
  const saveCommit = () => {
    loading.value = true
    switch (isType.value) {
      case 1:
        var { province, city, area } = singleAddressRef.value.getSelectAddr()
        YunxkUserObj.value.userProvince = province
        YunxkUserObj.value.userCity = city
        YunxkUserObj.value.userArea = area
        saveUserCfig(YunxkUserObj.value).then((res) => {
          if (res.data.code == 20000) {
            onPopCancel()
            ElMessage({
              message: res.data.message,
              duration: 5000,
              type: 'success',
              plain: true,
              showClose: true,
            })
          } else {
            ElMessageBox({
              message: res.data.message,
              type: 'error',
              title: '提示',
              autofocus: false,
            })
          }
          loading.value = false
        })
        break
      case 2:
        goodMaterialAsyncForm.value.goodsType =
          goodsMaterialAsyncActiveTab.value === 'product' ? 1 : 2
        if (!goodMaterialAsyncForm.value.goodsBrandId) {
          goodMaterialAsyncForm.value.goodsBrandId = 0
        }
        if (!goodMaterialAsyncForm.value.goodsTypeId) {
          goodMaterialAsyncForm.value.goodsTypeId = 0
        }
        saveGoodsCfig(goodMaterialAsyncForm.value).then((res) => {
          if (res.data.code === 20000) {
            onPopCancel()
            ElMessage({
              message: res.data.message,
              duration: 5000,
              type: 'success',
              plain: true,
              showClose: true,
            })
          } else {
            ElMessageBox({
              message: res.data.message,
              type: 'error',
              title: '提示',
              autofocus: false,
            })
          }
          loading.value = false
        })
        break
      case 3:
      case 4:
        var { province, city, area } = singleAddressRef.value.getSelectAddr()
        YunxkStoreCfig.value.storeProvince = province
        YunxkStoreCfig.value.storeCity = city
        YunxkStoreCfig.value.storeArea = area
        saveStoreCfig(YunxkStoreCfig.value).then((res) => {
          if (res.data.code === 20000) {
            onPopCancel()
            ElMessage({
              message: res.data.message,
              duration: 5000,
              type: 'success',
              plain: true,
              showClose: true,
            })
          } else {
            ElMessageBox({
              message: res.data.message,
              type: 'error',
              title: '提示',
              autofocus: false,
            })
          }
          loading.value = false
        })
        break
      case 5:
        break
      case 6:
        saveYunxkSaleStoreCfig(storeCfigVo.value).then((res) => {
          if (res.data.code == 20000) {
            onPopCancel()
            ElMessage({
              message: res.data.message,
              duration: 5000,
              type: 'success',
              plain: true,
              showClose: true,
            })
          } else {
            ElMessageBox({
              message: res.data.message,
              type: 'error',
              title: '提示',
              autofocus: false,
            })
          }
          loading.value = false
        })
        break
      case 7:
        saveOtherOutStoreCfig(reverseWritingCfigVo.value).then((res) => {
          if (res.data.code === 20000) {
            getUserData.value = {
              name: '',
              number: '',
            }
            onPopCancel()
            ElMessage({
              message: res.data.message,
              duration: 5000,
              type: 'success',
              plain: true,
              showClose: true,
            })
          } else {
            ElMessageBox({
              message: res.data.message,
              type: 'error',
              title: '提示',
              autofocus: false,
            })
          }
          loading.value = false
        })
        break
      case 8:
        break
      case 9:
        break
    }
  }
  const typeOptions = ref([])
  // 获取产品分类下拉
  const getTypeOptions = async (name) => {
    const data = {
      limit: 0,
      name: name,
      page: 0,
    }
    await typePageSelect(data).then((res) => {
      typeOptions.value = res.data.data.rows
    })
  }
  watch(
    () => typeVal.value,
    (newVal) => {
      if (newVal != '') {
        getTypeOptions(newVal)
      } else {
        getTypeOptions('')
      }
    },
  )

  // 同步进度
  const syncProgress = ref(0)

  // 进度同步定时器
  const syncProgressTimer = ref<NodeJS.Timeout | null>(null)

  /**
   * 开启定时器（进度同步定时器）
   */
  const startSyncProgressTimer = () => {
    syncProgress.value = 0
    syncProgressTimer.value = setInterval(() => {
      syncProgress.value = Number((syncProgress.value + 0.01).toFixed(2))
      if (dataReturned.value && !dataReturned.value.end && syncProgress.value >= 99.99) {
        stopSyncProgressTimer()
      }
    }, 1000)
  }

  /**
   * 关闭定时器（进度同步定时器）
   */
  const stopSyncProgressTimer = () => {
    if (syncProgressTimer.value) {
      clearInterval(syncProgressTimer.value)
    }
  }

  /**
   * 获取WebSocket返回的数据
   * @param {object} msg - WebSocket返回的数据
   */
  const msgHtml = ref([])
  const funProgress = (msg) => {
    dataReturned.value = msg
    if (msg.message) {
      msgHtml.value.push(msg?.message)
    }
    if (msg.end) {
      stopSyncProgressTimer()
    }
    scrollHeight()
    scrollHeight2()
    msg.end
  }
  // 滚动到底部
  const msgContentBoxs = ref()
  const scrollHeight = () => {
    nextTick(() => {
      if (msgContentBoxs.value) {
        msgContentBoxs.value.scrollTop = msgContentBoxs.value.scrollHeight
      }
    })
  }
  const msgContentBoxs2 = ref()
  const scrollHeight2 = () => {
    nextTick(() => {
      if (msgContentBoxs2.value) {
        msgContentBoxs2.value.scrollTop = msgContentBoxs2.value.scrollHeight
      }
    })
  }
  // 保存并同步
  const dataReturned = ref()
  const saveAsyncCommit = async () => {
    syncProgress.value = 0
    dataReturned.value = null
    msgHtml.value = []
    isMinAsync.value = true
    const uuid = new Date().getTime()
    initWebSocket(funProgress, `/ws/progress/${uuid}`)
    startSyncProgressTimer()
    let res: { code: number; message: string; data: object; success: boolean } | null = null
    loading.value = true
    switch (isType.value) {
      case 1:
        var { province, city, area } = singleAddressRef.value.getSelectAddr()
        YunxkUserObj.value.userProvince = province
        YunxkUserObj.value.userCity = city
        YunxkUserObj.value.userArea = area
        res = (await saveWithSyncUserCfig(YunxkUserObj.value, uuid)).data
        break
      case 2:
        goodMaterialAsyncForm.value.goodsType =
          goodsMaterialAsyncActiveTab.value === 'product' ? 1 : 2
        res = (await saveSyncGoods(goodMaterialAsyncForm.value, uuid)).data
        break
      case 3:
      case 4:
        var { province, city, area } = singleAddressRef.value.getSelectAddr()
        YunxkStoreCfig.value.storeProvince = province
        YunxkStoreCfig.value.storeCity = city
        YunxkStoreCfig.value.storeArea = area
        res = (await saveSyncStore(YunxkStoreCfig.value, uuid)).data
        break
      case 5:
        res = (await saveSyncOtherStore(uuid)).data
        break
      case 6:
        res = (await saveSyncYunxkSaleStore(storeCfigVo.value, uuid)).data
        break
      case 7:
        break
      case 8:
        break
      case 9:
        break
    }
    if (res) {
      if (res.code !== 20000) {
        ElMessageBox({
          message: res.message,
          type: 'error',
          title: '提示',
          autofocus: false,
        })
      }
    }
    loading.value = false
  }
  // 同步
  const loading_async = ref(false)
  const isBigAsync = ref(false)
  const isMinAsync = ref(false)
  const enableSynchronizationMsg = ref('')
  const asyncTypeShow = (type: number, goodsType = 1) => {
    ElMessageBox.confirm('确定同步此操作？', '提示', {
      confirmButtonText: '确定',
      type: 'warning',
      async beforeClose(action, instance, done) {
        if (['cancel', 'close'].includes(action)) {
          done()
        }

        if (action === 'confirm') {
          syncProgress.value = 0
          dataReturned.value = null
          msgHtml.value = []
          const uuid = new Date().getTime()
          initWebSocket(funProgress, `/ws/progress/${uuid}`)
          startSyncProgressTimer()
          instance.cancelButtonLoading = true
          instance.confirmButtonLoading = true
          let res: { code: number; message: string; success: boolean; data: object } | null = null
          switch (type) {
            case 1:
              res = (await syncUserCfig(uuid)).data
              break
            case 2:
              res = (await syncGoods(goodsType, uuid)).data
              break
            case 3:
            case 4:
              res = (await syncStore(uuid)).data
              break
            case 5:
              res = (await syncOtherStore(uuid)).data
              break
            case 6:
              res = (await syncYunxkSaleStore(uuid)).data
              break
            case 7:
              break
            case 8:
              break
            case 9:
              break
            case 10:
              res = (await saveAsyncSnCode(uuid)).data
              break
            case 11:
              res = (await syncWarehouseStock(uuid)).data
              break
            case 12:
              res = (await syncMountings(uuid)).data
              break
            case 13:
              res = (await productSyncData(uuid)).data
              break
          }
          instance.cancelButtonLoading = false
          instance.confirmButtonLoading = false
          if (res) {
            done()
            enableSynchronizationMsg.value = res.message
            if (res.code !== 20000) {
              ElMessageBox({
                message: res.message,
                type: 'error',
                title: '提示',
                autofocus: false,
              })
              return
            }
            isBigAsync.value = true
          }
        }
      },
    })
  }
  // const changeacctId = _.debounce(() => {
  //   if (!getYunxkCfigObj.value.path) {
  //     ElMessage({
  //       message: '请填写域名',
  //       duration: 3000,
  //       type: 'warning',
  //       plain: true,
  //     })
  //     return
  //   }
  //   let kingdeeYunxcSetVo = {
  //     enabled: getYunxkCfigObj.value.enabled,
  //     id: getYunxkCfigObj.value.id,
  //     path:
  //       selectHttps.value == '1'
  //         ? 'http://' + getYunxkCfigObj.value.path.replace(/^(https?:\/\/)/i, '')
  //         : 'https://' + getYunxkCfigObj.value.path.replace(/^(https?:\/\/)/i, ''),
  //     useOrg: getYunxkCfigObj.value.useOrg,
  //     useOrgId: getYunxkCfigObj.value.useOrgId,
  //   }
  //   getYunxkSetSave(kingdeeYunxcSetVo).then((res) => {
  //     if (res.data.code == 20000) {
  //       getYunxkCfigInfo()
  //       ElMessage({
  //         message: res.data.message,
  //         duration: 3000,
  //         type: 'success',
  //         plain: true,
  //       })
  //     } else {
  //       ElMessage({
  //         message: res.data.message,
  //         duration: 3000,
  //         type: 'error',
  //         plain: true,
  //       })
  //     }
  //   })
  // }, 800)
  // 保存星空接口状态
  const changeEnabled = _.debounce(() => {
    saveYunxkEnableCfig(getYunxkCfigObj.value.enabled).then((res) => {
      if (res.data.code !== 20000) {
        ElMessageBox({
          message: res.data.message,
          type: 'error',
          title: '提示',
          autofocus: false,
        })
      }
    })
  }, 500)
  // 保存星空域名
  const savePath = _.debounce(() => {
    if (!getYunxkCfigObj.value.path) {
      ElMessageBox({
        message: '请填写域名',
        type: 'warning',
        showClose: true,
        title: '提示',
      })
      return
    }
    let path =
      selectHttps.value == '1'
        ? 'http://' + getYunxkCfigObj.value.path.replace(/^(https?:\/\/)/i, '')
        : 'https://' + getYunxkCfigObj.value.path.replace(/^(https?:\/\/)/i, '')
    saveYunxkPathCfig(path).then((res) => {
      if (res.data.code === 20000) {
        ElMessage({
          message: res.data.message,
          duration: 5000,
          type: 'success',
          plain: true,
          showClose: true,
        })
        getStockOrgListFun()
        getYunxkCfigInfo()
      } else {
        ElMessageBox({
          message: res.data.message,
          type: 'error',
          title: '提示',
          autofocus: false,
        })
      }
    })
  }, 500)

  /**
   * 保存组织
   */
  const saveUseOrg = _.debounce(() => {
    let kingdeeYunxcSetVo = {
      useOrg: getYunxkCfigObj.value.useOrg,
      useOrgId: getYunxkCfigObj.value.useOrgId,
      useOrgNumber: getYunxkCfigObj.value.useOrgNumber,
    }
    saveYunxkOrgCfig(kingdeeYunxcSetVo).then((res) => {
      if (res.data.code === 20000) {
        ElMessage({
          message: res.data.message,
          duration: 5000,
          type: 'success',
          plain: true,
          showClose: true,
        })
      } else {
        ElMessageBox({
          message: res.data.message,
          type: 'error',
          title: '提示',
          autofocus: false,
        })
      }
    })
  }, 500)

  // 创建一个下载文件的函数
  function downloadFile(filePath) {
    // 获取当前页面的域名（不包括协议和端口）
    var domain = window.location.origin // window.location.origin 会返回完整的协议+域名+端口（如果有的话）
    if (isLocalOrIP()) {
      domain = 'https://saas.1688-yun.com'
    }
    // 构建完整的下载URL
    var downloadUrl = domain + filePath
    // 创建一个新的a标签元素
    var a = document.createElement('a')
    a.href = downloadUrl
    if (filePath.includes('pdf')) {
      a.target = '_blank'
    }

    // a.download = '金蝶云星空配置包.zip'; // 设置下载文件的名称
    a.style.display = 'none' // 隐藏a标签
    // 触发点击事件开始下载
    document.body.appendChild(a) // 必须添加到DOM中才能触发点击
    a.click()
    document.body.removeChild(a) // 下载完成后移除元素
    if (filePath.includes('pdf')) return
    ElMessage({
      message: '正在下载中...',
      duration: 5000,
      type: 'success',
      plain: true,
      showClose: true,
    })
  }
  function isLocalOrIP() {
    const hostname = window.location.hostname
    // 判断是否为localhost
    if (hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '::1') {
      return true
    }
    // 判断是否为IP地址
    // 这里我们使用了一个简单的正则表达式来匹配IPv4地址
    // 注意：这个正则表达式不会匹配IPv6地址
    const ipPattern =
      /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
    if (ipPattern.test(hostname)) {
      return true
    }
    // 如果不是本地开发环境也不是IP地址，则认为是普通域名
    return false
  }
  // 下载配置包
  const downLoad = _.debounce(() => {
    var filePath = '/app-load/kingdee/yunxk/kingdee-yunxk.zip' // 这里是你文件相对于域名的路径
    downloadFile(filePath)
  }, 500)
  const downLoadPDF = () => {
    var filePath = '/app-load/kingdee/yunxk/金蝶云星空&售后配置包使用手册.pdf' // 这里是你文件相对于域名的路径
    downloadFile(filePath)
  }
  // 关闭弹窗
  const onPopCancel = () => {
    popRightDialog.value = false
    dataReturned.value = null
    msgHtml.value = []
  }

  /**
   * 关闭同步弹窗
   */
  const onCloseSynchronizationDialog = () => {
    if (dataReturned.value && dataReturned.value.end) {
      dataReturned.value = null
      isBigAsync.value = false
      isMinAsync.value = false
    }
  }

  onMounted(() => {
    loading_async.value = true
    Promise.all([getYunxkCfigInfo(), getStockOrgListFun()]).then(() => {
      loading_async.value = false
    })
  })
</script>

<style scoped lang="scss">
  @import './index';
</style>
